<template>
  <div class="head-container">
    <el-input v-model="menuName" class="mb-20px" clearable placeholder="请输入目录名称">
      <template #prefix>
        <Icon icon="ep:search" />
      </template>
    </el-input>
  </div>
  <div class="head-container">
    <el-tree
        ref="treeRef"
        :data="menuList"
        :expand-on-click-node="false"
        :filter-node-method="filterNode"
        :props="treeProps"
    default-expand-all
    highlight-current
    node-key="id"
    @node-click="handleNodeClick"
    />
  </div>
</template>

<script lang="ts" setup>
// 导入Element Plus Tree组件及类型
import { ElTree } from 'element-plus'
import type { TreeInstance, TreeProps } from 'element-plus'
// 导入目录API和树形工具类
import * as CataLogApi from '@/api/business/cataLog'
import { handleTree } from '@/utils/tree'
// Vue核心API
import { ref, watch, onMounted, defineEmits, defineOptions } from 'vue'

// 页面配置
defineOptions({ name: 'BusinessPortMenuTree' })

// -------------------------- 类型定义（匹配你的数据结构） --------------------------
interface menuTree {
  id: number | string;          // 节点唯一ID（保持与node-key一致）
  menuName: string;            // 节点名称（替换原name）
  classifySj: number | string; // 父节点ID（替换原parentId）
  children?: menuTree[];     // 子节点列表（树形结构必备）
  [key: string]: any;          // 其他扩展字段
}

// -------------------------- 响应式数据 --------------------------
const menuName = ref('')                          // 搜索框绑定值（目录名称搜索）
const menuList = ref<menuTree[]>([])        // 目录树形数据
const treeRef = ref<InstanceType<typeof ElTree>>()// Tree组件实例引用
let currentNode: menuTree | null = null        // 当前选中的节点（用于处理选中/取消逻辑）

// -------------------------- 树形配置（核心：映射menuName和classifySj） --------------------------
// 自定义TreeProps，明确指定label为menuName、children为children、parentId为classifySj
const treeProps: TreeProps = {
  label: 'menuName',        // 树节点显示的名称字段（你的数据字段：menuName）
  children: 'children',     // 子节点数组字段（默认children，若接口返回不同需调整）
  parentKey: 'classifySj'   // 父节点ID字段（你的数据字段：classifySj，替代默认parentId）
}

// -------------------------- 方法定义 --------------------------
/**
 * 获取目录树数据
 * 调用接口后，通过handleTree工具类将扁平数据转为树形结构（基于classifySj关联父节点）
 */
const getTree = async () => {
  try {
    const res = await CataLogApi.getSimpleMenuList()
    // 清空原有数据，避免重复
    menuList.value = []
    // 处理扁平数据为树形结构（handleTree需支持parentKey为classifySj，若不支持需调整工具类，见下方说明）
    const treeData = handleTree(res, 'id', 'classifySj') // 显式指定id和parentKey字段
    menuList.value.push(...treeData)
    console.log('目录树形数据：', menuList.value)
  } catch (error) {
    console.error('获取目录树失败：', error)
    menuList.value = []
  }
}

/**
 * 基于目录名称（menuName）过滤树节点
 * @param filterValue 搜索框输入的过滤值
 * @param nodeData 当前树节点数据
 * @returns 是否匹配过滤条件
 */
const filterNode = (filterValue: string, nodeData: MenuTree) => {
  if (!filterValue) return true // 无过滤值时显示所有节点
  // 匹配节点的menuName字段（忽略大小写，提高用户体验）
  return nodeData.menuName.toLowerCase().includes(filterValue.toLowerCase())
}

/**
 * 处理目录节点点击事件（支持选中/取消选中）
 * @param row 当前点击的节点数据
 * @param treeNode Element Plus Tree节点实例
 */
const handleNodeClick = async (row: MenuTree, treeNode: any) => {
  // 判断是否点击已选中的节点（实现切换选中/取消）
  if (currentNode && currentNode.id === row.id) { // 用id判断唯一性，比name更可靠
    treeNode.checked = !treeNode.checked
  } else {
    treeNode.checked = true // 点击新节点时默认选中
  }

  if (treeNode.checked) {
    // 选中节点：记录当前节点并触发事件
    currentNode = row
    emits('node-click', row) // 向父组件传递选中的节点数据
  } else {
    // 取消选中：清空当前节点、取消高亮、触发空事件
    currentNode = null
    treeRef.value?.setCurrentKey(undefined) // 取消节点高亮
    emits('node-click', undefined) // 向父组件传递取消选中的信号
  }
}

// -------------------------- 事件与监听 --------------------------
// 定义向父组件暴露的事件
const emits = defineEmits<{
  (e: 'node-click', value: menuTree | undefined): void
}>()

// 监听搜索框变化，实时过滤树节点
watch(menuName, (filterValue) => {
  treeRef.value?.filter(filterValue)
})

// -------------------------- 页面初始化 --------------------------
onMounted(async () => {
  await getTree() // 初始化加载目录树
})
</script>

<style scoped>
/* 目录树容器样式（保持原有风格） */
.head-container {
  width: 100%;
  box-sizing: border-box;
}

/* 搜索框下边距 */
.mb-20px {
  margin-bottom: 20px;
}

/* 树节点容器高度适配（可根据实际需求调整） */
.el-tree {
  max-height: calc(100vh - 120px);
  overflow-y: auto;
}
</style>
